package edu.mti.csi.amaml.xml;

import java.io.IOException;

import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.SchemaFactory;

import org.xml.sax.SAXException;

/**
 * Performs XML documents validation with XML Schema Definitions.
 *
 */
public class XSDValidator
{
	/**
	 * Language of the XML Schema Definition.
	 */
	private final String SCHEMA_LANG = "http://www.w3.org/2001/XMLSchema";

	/**
	 * Path of the XML document to validate.
	 */
	private String xmlPath;
	
	/**
	 * Path of the XML Schema Definition that validates XML document.
	 */
	private String xsdPath;
	
	
	/**
	 * Performs XML documents validation with XML Schema Definitions.
	 * SINTAX: xsdvalidator xml_file xsd_file
	 * @param args
	 * xml_file: Path of the XML document to validate.
	 * xsd_file: Path of the XML Schema Definition that validates XML document.
	 */
	public static void main(String[] args)
	{
		XSDValidator xsdv = new XSDValidator();
		
		if (xsdv.validateParameters(args))
		{
			try
			{
				xsdv.validate();
				System.out.println("XML document is valid!");
				System.exit(0);
			}
			catch (SAXException e)
			{
				System.out.println("XML document is not valid:");
				System.err.println("- Error while validating XML (" + e.getMessage() + ").");
				System.exit(2);
			}
			catch (IOException e)
			{
				System.err.println("Error while reading XML (" + e.getMessage() + ").");
				System.exit(3);
			}
			catch (Exception e)
			{
				System.err.println("Error while validating XML (" + e.getMessage() + ").");
				System.exit(4);
			}
		}
		else
		{
			System.out.println("SINTAX: xsdvalidator xml_file xsd_file");
			System.out.println("	xml_file: Path of the XML document to validate.");
			System.out.println("	xsd_file: Path of the XML Schema Definition that validates XML document.");
			System.exit(1);
		}
	}
	
	public XSDValidator()
	{
		super();
	}
	
	public XSDValidator(String xmlPath, String xsdPath)
	{
		super();
		this.xmlPath = xmlPath;
		this.xsdPath = xsdPath;
	}

	public String getXmlPath()
	{
		return xmlPath;
	}

	public void setXmlPath(String xmlPath)
	{
		this.xmlPath = xmlPath;
	}

	public String getXsdPath()
	{
		return xsdPath;
	}

	public void setXsdPath(String xsdPath)
	{
		this.xsdPath = xsdPath;
	}

	public boolean validateParameters(String[] args)
	{
		boolean valid = true;
		
		if (args.length != 2)
		{
			valid = false;
		}
		else
		{
			this.xmlPath = args[0];
			this.xsdPath = args[1];
		}
		
		return valid;
	}
	
	/**
	 * Validates an XML document with an XML Schema Definition.
	 * @param xml Path of the XML document that is validated.
	 * @param xsd Path of the XML Schema Definition that validates the XML document.
	 * @throws SAXException 
	 * @throws IOException 
	 */
	public void validate() throws SAXException, IOException
	{
		SchemaFactory.newInstance(SCHEMA_LANG).newSchema(new StreamSource(this.xsdPath)).newValidator().validate(new StreamSource(this.xmlPath));
	}
}
